const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("reject 1");
    resolve(1);
  }, 1000);
});
const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("reject 2");
    resolve(2);
  }, 200);
});
const p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("reject 3");
    resolve(3)
  }, 1600);
});
const p4 = new Promise((resolve, reject) => {
  setTimeout(() => {
    reject("reject 4");
    resolve(4)
  }, 500);
});

Promise.myRace = function (iter) {
  return new Promise(async function (resolve, reject) {
    for (const element of iter) {
      element.then(resolve, reject);
    }
  });
};
Promise.myAny = function (iter) {
    const err = []
    let count = 0, i = 0
    return new Promise(async function (resolve, reject) {
      for (const element of iter) {
        const index = i
        i++
        element.then(resolve, r => {
            count++
            err[index] = r
            if(count === iter.length) {
                reject(new AggregateError(err))
            }
        });
      }
    });
  };
Promise.myAllSettled = function (iter) {
  const result = [];
  let i = 0,
    count = 0;
  return new Promise(async function (resolve, reject) {
    for (const element of iter) {
      const index = i;
      i++;
      Promise.resolve(element)
        .then((v) => {
          result[index] = {
            status: "fulfilled",
            value: v,
          };
        })
        .catch((v) => {
          result[index] = {
            status: "rejected",
            reason: v,
          };
        })
        .finally(() => {
          count++;
          if (count === iter.length) {
            resolve(result);
          }
        });
    }
  });
};

Promise.myAll = function (iter) {
  const result = [];
  let i = 0,
    count = 0;

  return new Promise(async function (resolve, reject) {
    for (const element of iter) {
      const index = i;
      i++;
      Promise.resolve(element).then((v) => {
        result[index] = v;
        count++;
        if (count === iter.length) {
          resolve(result);
        }
      }, reject);
    }
  });
};
Promise.all([p1, p2, p3, p4]).then(
  (v) => console.log("all", v),
  (err) => console.log("all", err)
);
Promise.myAll([p1, p2, p3, p4]).then(
  (v) => console.log("myAll", v),
  (err) => console.log("myAll", err)
);
Promise.race([p1, p2, p3, p4]).then(
  (v) => console.log("race", v),
  (err) => console.log("race", err)
);
Promise.myRace([p1, p2, p3, p4]).then(
  (v) => console.log("myRace", v),
  (err) => console.log("myRace", err)
);
Promise.allSettled([p1, p2, p3, p4]).then(
  (v) => console.log("allSettled", v),
  (err) => console.log("allSettled", err)
);
Promise.myAllSettled([p1, p2, p3, p4]).then(
  (v) => console.log("myAllSettled", v),
  (err) => console.log("myAllSettled", err)
);
Promise.any([p1, p2, p3, p4]).then(
  (v) => console.log("any", v),
  (err) => console.log("any", err)
);
Promise.myAny([p1, p2, p3, p4]).then(
    (v) => console.log("myAny", v),
    (err) => console.log("myAny", err)
  );

